package com.shuma.upms.user.service.impl;

import com.shuma.upms.user.api.feign.PermissionServiceFeignClient;
import com.shuma.upms.user.domain.entity.Result;
import com.shuma.upms.user.exception.BusinessException;
import com.shuma.upms.user.mapper.UserMapper;
import com.shuma.upms.user.service.PermissionCheckService;
import com.shuma.upms.user.util.UserContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Service
public class PermissionCheckServiceImpl implements PermissionCheckService {

    @Autowired
    private PermissionServiceFeignClient permissionServiceFeignClient;
    @Autowired
    private UserMapper userMapper;


    @Override
    public String getOperatorRole() {
        Long operatorId = UserContextHolder.getUserId();
        if (operatorId == null) {
            throw new BusinessException("无法获取当前操作者信息，请先登录");
        }
        return getUserRole(operatorId);
    }

    @Override
    public String getUserRole(Long userId) {
        Result<String> roleResult = permissionServiceFeignClient.getUserRoleCode(userId);
        if (roleResult.getCode() != 0 || roleResult.getData() == null) {
            log.error("获取用户[id={}]角色失败: {}", userId, roleResult.getMessage());
            throw new BusinessException("获取用户角色信息失败");
        }
        return roleResult.getData();
    }

    @Override
    public void checkWritePermission(Long targetUserId) {
        Long operatorId = UserContextHolder.getUserId();
        String operatorRole = getOperatorRole();

        log.debug("权限检查：操作者[id={}, role={}] 尝试写入用户[id={}] 的数据", operatorId, operatorRole, targetUserId);

        if (ROLE_SUPER_ADMIN.equals(operatorRole)) {
            log.debug("权限检查通过：操作者是超级管理员。");
            return;
        }

        if (Objects.equals(operatorId, targetUserId)) {
            log.debug("权限检查通过：用户正在修改自己的信息。");
            return;
        }

        if (ROLE_ADMIN.equals(operatorRole)) {
            String targetUserRole = getUserRole(targetUserId);
            if (ROLE_USER.equals(targetUserRole)) {
                log.debug("权限检查通过：管理员正在修改普通用户的信息。");
                return;
            }
        }

        log.warn("权限不足：操作者[id={}, role={}] 无法写入用户[id={}] 的数据", operatorId, operatorRole, targetUserId);
        throw new BusinessException("权限不足，无法操作");
    }

    // 数据读取的权限检查
    @Override
    public void checkReadPermission(Long targetUserId) {
        Long operatorId = UserContextHolder.getUserId();
        String operatorRole = getOperatorRole();

        log.debug("权限检查：操作者[id={}, role={}] 尝试读取用户[id={}] 的数据", operatorId, operatorRole, targetUserId);

        // 规则1：超级管理员可以查看任何人
        if (ROLE_SUPER_ADMIN.equals(operatorRole)) {
            log.debug("权限检查通过：操作者是超级管理员。");
            return;
        }

        // 规则2：用户可以查看自己
        if (Objects.equals(operatorId, targetUserId)) {
            log.debug("权限检查通过：用户正在查看自己的信息。");
            return;
        }

        // 规则3：管理员可以查看任何非超级管理员的用户
        if (ROLE_ADMIN.equals(operatorRole)) {
            String targetUserRole = getUserRole(targetUserId);
            if (!ROLE_SUPER_ADMIN.equals(targetUserRole)) {
                log.debug("权限检查通过：管理员正在查看非超级管理员的信息。");
                return;
            }
        }

        // 如果以上规则都不满足，则抛出权限不足异常
        log.warn("权限不足：操作者[id={}, role={}] 无法读取用户[id={}] 的数据", operatorId, operatorRole, targetUserId);
        throw new BusinessException("权限不足，无法查看该用户信息");
    }

    // 角色更新权限检查
    @Override
    public void checkRoleUpdatePermission(Long targetUserId, String newRoleCode) {
        // 1. 获取操作者角色
        String operatorRole = getOperatorRole();

        log.info("权限检查：操作者[role={}] 尝试将用户[id={}]的角色变更为[{}]。",
                operatorRole, targetUserId, newRoleCode);

        // 2. 只有超级管理员才能修改角色
        if (!ROLE_SUPER_ADMIN.equals(operatorRole)) {
            log.warn("权限不足：非超级管理员[role={}]尝试修改角色。", operatorRole);
            throw new BusinessException("权限不足，只有超级管理员才能修改角色");
        }

        // 3. 超管不能修改自己的角色
        Long operatorId = UserContextHolder.getUserId();
        if (Objects.equals(operatorId, targetUserId)) {
            log.warn("危险操作阻止：超级管理员[id={}]尝试修改自己的角色。", operatorId);
            throw new BusinessException("为安全起见，超级管理员不能修改自己的角色");
        }

        // 4. 检查目标角色是否合法
        if (!ROLE_ADMIN.equals(newRoleCode) && !ROLE_USER.equals(newRoleCode)) {
            throw new BusinessException("无效的目标角色代码: " + newRoleCode);
        }

        log.info("权限检查通过：超级管理员有权进行此角色变更操作。");
    }



}